package com.tangguangdi.base.db.generator.service;

import com.tangguangdi.base.db.generator.query.IDbQuery;
import com.tangguangdi.base.db.generator.query.MySqlQuery;
import com.tangguangdi.base.db.properties.DbProperties;
import com.tangguangdi.base.db.properties.GeneratorProperties;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DbService {

    @Resource
    private DataSource dataSource;

    private DbProperties dbProperties;

    public DbService(DbProperties dbProperties) {
        this.dbProperties = dbProperties;
    }

    /**
     * 获取基础配置
     */
    public GeneratorProperties generatorProperties() {
        return dbProperties.getGenerator();
    }

    /**
     * 获取查询配置
     */
    public IDbQuery dbQuery() {
        switch (dbProperties.getGenerator().getType()) {
            case "MYSQL":
            default:
                return new MySqlQuery();
        }
    }

    /**
     * 获取当前应用的数据库连接
     */
    public Connection connect() throws SQLException {
        Connection connection = dataSource.getConnection();
        connection.setSchema(dbProperties.getGenerator().getSchema());
        return connection;
    }

    /**
     * 查询sql并释放连接
     */
    public List<Map> queryAndClose(Connection connection, String sql) throws SQLException {
        List<Map> result = query(connection, sql);
        connection.close();
        return result;
    }

    /**
     * 查询sql并返回结果
     */
    public List<Map> query(Connection connection, String sql) throws SQLException {
        if (connection.isClosed()) return new ArrayList<>();
        List<Map> result = new ArrayList<>();
        Statement statement = connection.createStatement();
        ResultSet resultSet = statement.executeQuery(sql);
        ResultSetMetaData md = resultSet.getMetaData();
        while (resultSet.next()) {
            Map<String, Object> rowData = new HashMap<>();
            for (int i = 1; i <= md.getColumnCount(); i++) {
                rowData.put(md.getColumnLabel(i), resultSet.getObject(i));
            }
            result.add(rowData);
        }
        resultSet.close();
        statement.close();
        return result;
    }

    /**
     * 执行sql并释放连接
     */
    public int updateAndClose(Connection connection, String sql) throws SQLException {
        int result = update(connection, sql);
        connection.close();
        return result;
    }

    /**
     * 执行sql并返回结果
     */
    public int update(Connection connection, String sql) throws SQLException {
        if (connection.isClosed()) return 0;
        Statement statement = connection.createStatement();
        int resultInt = statement.executeUpdate(sql);
        statement.close();
        return resultInt;
    }

}
